package com.qeng.aiwanba.net;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

import com.qeng.aiwanba.util.DeviceUtil;
import com.qeng.aiwanba.util.Util;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class QYHttpUtils {

    private static ExecutorService sThreadPool = Executors.newFixedThreadPool(4);
    private static Handler sHandler = new Handler(Looper.getMainLooper());
    private static int sTimeout = 20000;

    public interface RequestCallback<T> {
        void success(T result);
        void failure(Exception e);
    }

    // 设置http缓存
    public static void enableHttpResponseCache(Context context) {
        try {
            long httpCacheSize = 10 * 1024 * 1024;
            File httpCacheDir = new File(context.getCacheDir(), "http");
            Class.forName("android.net.http.HttpResponseCache")
                    .getMethod("install", File.class, long.class)
                    .invoke(null, httpCacheDir, httpCacheSize);
        } catch (Exception httpResponseCacheNotAvailable) {
        }
    }

    public static void doGet(final Context context,final String urlString, final Map<String, String> params, final RequestCallback<String> listener) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                final Map<String, String> signParams = getSignParams(context,params);
                HttpURLConnection connection = null;
                InputStream is = null;
                BufferedReader br = null;
                try {
                    String newUrlString;
                    String paramsUrl = getUrlFromParams(signParams);
                    if (!TextUtils.isEmpty(paramsUrl)) {
                        newUrlString = urlString + "?" + paramsUrl;
                    } else {
                        newUrlString = urlString;
                    }
                    URL url = new URL(newUrlString);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setConnectTimeout(sTimeout);
                    connection.setReadTimeout(sTimeout);
                    if (connection.getResponseCode() != 200) {
//                        throw new QYApiException("服务器出错啦");
                    }
                    is = connection.getInputStream();
                    br = new BufferedReader(new InputStreamReader(is));
                    final StringBuilder sb = new StringBuilder();
                    String readLine;
                    while((readLine = br.readLine()) != null){
                        sb.append(readLine);
                    }
                    sHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            listener.success(sb.toString());
                        }
                    });
                } catch (final Exception e) {
                    sHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            listener.failure(e);
                        }
                    });
                } finally {
                    connection.disconnect();
                    closeStream(is, br);
                }
            }
        };
        sThreadPool.submit(runnable);
    }

    public static void doPost(final Context context,final String urlString, final Map<String, String> params, final RequestCallback<String> listener) {
        Log.e("tag","request url:"+urlString);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                final Map<String, String> signParams = getSignParams(context,params);
                HttpURLConnection connection = null;
                InputStream is = null;
                BufferedReader br = null;
                try {
                    try {
                        SSLContext sc = SSLContext.getInstance("TLS");
                        sc.init(null, new TrustManager[]{new MyTrustManager()}, new SecureRandom());
                        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
                        HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());
                    } catch (Exception e) {

                    }
                    URL url = new URL(urlString);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setConnectTimeout(sTimeout);
                    connection.setReadTimeout(sTimeout);
                    connection.setDoInput(true);
                    connection.setDoOutput(true);
                    connection.setRequestMethod("POST");
                    connection.setUseCaches(false);
                    connection.setInstanceFollowRedirects(false);
                    connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                    connection.connect();

                    String content = getUrlFromParams(signParams);
                    Log.e("tag","request params:"+content);
                    if (!TextUtils.isEmpty(content)) {
                        DataOutputStream out = new DataOutputStream(connection.getOutputStream());
                        out.writeBytes(content);
                        out.flush();
                        out.close();
                    }
                    Log.e("tag","responseCode:"+connection.getResponseCode());
                    if (connection.getResponseCode() != 200) {
//                        throw new QYApiException("服务器出错啦");
                    }
                    is = connection.getInputStream();
                    br = new BufferedReader(new InputStreamReader(is));
                    final StringBuilder sb = new StringBuilder();
                    String readLine;
                    while((readLine = br.readLine()) != null){
                        sb.append(readLine);
                    }
                    sHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            Log.e("tag","response:"+sb.toString());
                            try {
                                JSONObject object = new JSONObject(sb.toString());
//                                Log.e("tag","object:"+object.toString().replaceAll("'","\\\\'"));
//                                String data = "'";
//                                Log.e("tag","data:"+data.replaceAll("'","\\\\'"));
                                listener.success(object.toString());
                            } catch (JSONException e) {
//                                e.printStackTrace();
                                listener.success(null);
                            }
                        }
                    });
                } catch (final Exception e) {
                    e.printStackTrace();
                    sHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            listener.failure(e);
                        }
                    });
                } finally {
                    connection.disconnect();
                    closeStream(is, br);
                }
            }
        };
        sThreadPool.submit(runnable);
    }

    // 将Map连接成key1＝value1&key2=value2.
    private static String getUrlFromParams(Map<String, String> params) {
        if (null == params) {
            return null;
        }
        final StringBuilder sb = new StringBuilder();
        try {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                sb.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
                sb.append('=');
                sb.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
                sb.append('&');
            }
            if (sb.length() > 0) {
                sb.delete(sb.length() - 1, sb.length());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    private static Map<String, String> getSignParams(Context context,Map<String, String> params) {
        Map<String, String> signParams = new TreeMap<String, String>();
        // 添加通用的参数
        signParams.put("platform", "1");
        signParams.put("udid", DeviceUtil.udid());
        signParams.put("model", DeviceUtil.deviceModel());
        signParams.put("os", DeviceUtil.deviceOs());
        signParams.put("appid", "");
        signParams.put("r", DeviceUtil.appR());
        signParams.put("t", String.valueOf(System.currentTimeMillis()));

        signParams.put("idfa",DeviceUtil.udid());
        signParams.put("ios_or_android","android");

        signParams.put("adid", DeviceUtil.deviceAndroidId(context));
        signParams.put("imei", DeviceUtil.deviceImei(context));
        signParams.put("mac", DeviceUtil.deviceMac(context));
        signParams.put("brand", DeviceUtil.deviceBrand());
        signParams.put("ch", "");
        signParams.put("version", Util.getVersion(context));


        if (null != params) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                signParams.put(entry.getKey(), entry.getValue());
            }
        }
        // 拼接sign
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : signParams.entrySet()) {
            // 如果value为空，只改成""
            if (TextUtils.isEmpty(entry.getValue())) {
                signParams.put(entry.getKey(), "");
            }
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        if (sb.length() > 0) {
            sb.delete(sb.length() - 1, sb.length());
        }
        Log.e("tag","sign string:"+sb.toString());
        signParams.put("sign", QYRSAUtil.sign(sb.toString()));
        return signParams;
    }

    private static void closeStream(Closeable... closeables) {
        for (Closeable stream: closeables) {
            if (null != stream) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static class MyHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

    private static class MyTrustManager implements X509TrustManager {
        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
        }
        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType)

                throws CertificateException {
        }
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }
}
